﻿using CPPEI.Coolzon.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.ServiceProxy
{
    /// <summary>
    /// 主服务代理类，
    /// 这个类存放了主服务的基本信息，每一个主服务配置都会对应一个实例。
    /// </summary>
    public class MainServiceProxy
    {
        public string IP { get; set; }
        public int Port { get; set; }
        private Configuration.Client.ServiceConfig _spareConfig;
        private MainServiceRef.IMainServiceCallback _callbackImplement;
        public MainServiceRef.MainServiceClient Client { get; set; }

        public ServiceProxyState State { get; set; }

        /// <summary>
        /// 构建主服务代理
        /// </summary>
        /// <param name="spareConfig"></param>
        /// <param name="callbackImplement"></param>
        public MainServiceProxy(Configuration.Client.ServiceConfig spareConfig,
            MainServiceRef.IMainServiceCallback callbackImplement)
        {
            this.IP = spareConfig.IP;
            this.Port = spareConfig.Port;
            _spareConfig = spareConfig;
            _callbackImplement = callbackImplement;

            this.Client = CreateMainServiceClient(_spareConfig, _callbackImplement);

            State = ServiceProxyState.Disconnected;
        }

        /// <summary>
        /// 新建一个新的Client对象，并打开连接
        /// </summary>
        /// <returns></returns>
        public bool Reconnect()
        {
            if (this.Client != null)
            {
                if (this.Client.State == CommunicationState.Opened)
                {
                    return true;
                }
            }

            try
            {
                this.Client = CreateMainServiceClient(_spareConfig, _callbackImplement);
                this.Client.Open();
                return true;
            }
            catch (Exception ex)
            {
                //Common.Logger.ErrorToTag("ServiceProxy", "重新建立连接ip:{0},port:{1}失败,ex:{2}",
                //    _spareConfig.IP,
                //    _spareConfig.Port,
                //    ex);
                return false;
            }
        }

        /// <summary>
        /// 设置连接状态为“ServiceProxyState.Disconnected”，同时将Client对象关闭
        /// </summary>
        public void GoToDisconnectState()
        {
            Logger.DebugToTag(Library.LogTAG, "MainServerProxy{0}:{1},设置State为{2}", this.IP,
                this.Port,
                ServiceProxyState.Disconnected);
            this.State = ServiceProxyState.Disconnected;
            if (this.Client != null)
            {
                this.Client.Abort();
                this.Client.Close();
                this.Client = null;
                Logger.DebugToTag(Library.LogTAG, "MainServerProxy{0}:{1},关闭Client对象", this.IP,
                    this.Port);
            }
        }

        /// <summary>
        /// 初始化主服务的网络客户端实例
        /// </summary>
        /// <param name="callbackImplement">回调接口实现</param>
        /// <returns></returns>
        private static MainServiceRef.MainServiceClient CreateMainServiceClient(Configuration.Client.ServiceConfig serviceConfig,
            MainServiceRef.IMainServiceCallback callbackImplement)
        {
            System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding();
            (tcpBinding as NetTcpBinding).Security.Mode = SecurityMode.None;
            EndpointAddress address = new EndpointAddress(string.Format("net.tcp://{0}:{1}/{2}/", serviceConfig.IP, serviceConfig.Port, serviceConfig.Path));

            System.ServiceModel.InstanceContext context = new InstanceContext(callbackImplement);
            MainServiceRef.MainServiceClient s_mainServiceClient = new MainServiceRef.MainServiceClient(context, tcpBinding, address);
            return s_mainServiceClient;
        }
    }

    public enum ServiceProxyState
    {
        /// <summary>
        /// 针对SyncService添加的，MainService还没用上
        /// 已经初始化，但是还没有打开连接，打开之后变成Conncted,打开失败变成Disconnected
        /// </summary>
        Inited,
        /// <summary>
        /// 已连接
        /// </summary>
        Connected,
        /// <summary>
        /// 重新连接中
        /// </summary>
        Reconnecting,
        /// <summary>
        /// 连接中
        /// </summary>
        Connecting,
        /// <summary>
        /// 连接失败，但是网络没有错，只是服务器返回结果告知连接不正确
        /// 可能是展示端连接的时候，服务器上没有域信息
        /// 域信息只有控制端重连的时候才可以用
        /// </summary>
        ReconnectFailure,
        /// <summary>
        /// 重新连接完成，当心跳线程扫描到这个状态的时候，
        /// 将状态修改为Connected，下一次即可正常进行心跳了。
        /// </summary>
        ReconnectFinished,
        /// <summary>
        /// 断开连接
        /// </summary>
        Disconnected,
    }
}
